
/*
 *
 */
package cis36b.project1;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.*;
import java.awt.image.BufferedImage;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import javax.swing.*;
import javax.imageio.*;
import java.io.*;
import java.lang.*;
import java.io.File;

/**
 * The Board class encapsulates all the visual aspects of the game. Board 
 * extends JPanel so it can be treated as a swing component. The Board class 
 * does not handled any of the game Logic.
 * 
 * The available functions are supposed to be:
 * loadImageResources()//loads images into memory
 * BufferedImage scaleImage()//scales images to the desired size
 * resizeBoard(cols, rows, pixels)//needs to interface with the UI (called by an actionListener)
 * paintBG()                //not implemented yet! tiles scaledBGimage 
 * drawGameState(gameState) //not implemented yet!
 * 
 * !I need to add an actionListener to get parameters from the UI component!
 * @author Jonah
 */
public class Board extends JPanel {
    
    //these are cals to the graphics instances, I'm not sure exatly how they work yet
    //private Graphics g = this.getGraphics();
    //private Graphics2D g2d = (Graphics2D) g;
    
    private BufferedImage originalBGimage;
    private BufferedImage scaledBGimage;// this needs to be image not bufferedImage?
    private String userDir = System.getProperty("user.dir");
    //for the time being these are the default parameters, until I can set up an
    //actionListener to get user defined parameters from the UI panel
    public int pixelsPerSquare = 20;//default to 20
    public int columns = 24;
    public int rows = 24;
    
    public ImageOperations imageOps = new ImageOperations();
    
    //constructor
    public Board(){
        System.out.println("Board constructor called");
        //System.out.println("this:" + this.toString());
        LoadImageResources();
        resizeBoard(columns, rows, pixelsPerSquare);
        //System.out.println("Board constructor called");
        //paintBG( g );
        //paintTest( g);
        //System.out.println(this.getGraphics());
    }
    
    //directory tester, maybe removed later on. used to check where java thinks 
    //its user directory is
    private void testDirectory() {
        String path = userDir; 

        String files;
        File folder = new File(path);
        File[] listOfFiles = folder.listFiles(); 

        for (int i = 0; i < listOfFiles.length; i++) 
        {

        if (listOfFiles[i].isFile()) {
        files = listOfFiles[i].getName();
        System.out.println(files);
            }
        }
    }
    
    private void LoadImageResources() {
        //originalBGimage = loadImage("src/cis36b/project1/resources/bgTile.png");
        originalBGimage = imageOps.loadImage("src/cis36b/project1/resources/bgTile.png");
    }
    
    /**
     * Used for loading images, returns a buffered image
     * 
     * @param filepath
     * @return 
     */
    private BufferedImage loadImage(String filepath){
        try{
            return ImageIO.read(new File(filepath));
        } catch (IOException e) { System.out.println("loadImage failed");}
        return null;
    }
    
    //method used for testing only
    public void resetBoard() {
        resizeBoard(columns, rows, pixelsPerSquare);
    }
    
    /**
     * Hopefully this code should work. (done-working!)
     * @param cols
     * @param rows
     * @param pixels 
     */
    private void resizeBoard( int cols, int rows, int pixels) {
        int width  = cols*pixels;
        int height = rows*pixels;
        this.setPreferredSize( new Dimension( width, height ));
        scaledBGimage = imageOps.resize(originalBGimage, pixels, pixels);
        //scaledBGimage = scaleImage( originalBGimage, pixels);
        //testing output
        System.out.println("resize board Dimensioans:" + width + "x" + height);
    }
    
    /**
     * this code came from http://helpdesk.objects.com.au/java/how-do-i-scale-a-bufferedimage.
     * this code is not working!
     * 
     * @param originalImg
     * @param newDim
     * @return 
     */
    /*---found better function, this is just kept in here for  documentation sake
    private BufferedImage scaleImage( BufferedImage originalImg, int newDim) {
        //this creates a blank BufferedImage in the size we want to scale to
        BufferedImage scaledImage = new BufferedImage( newDim, newDim, BufferedImage.TYPE_INT_ARGB);
        
        //then we repaint the original onto the scaled blank
        Graphics2D graphics2D = scaledImage.createGraphics();
        graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        
        //clean up the graphics
        graphics2D.dispose();
        System.out.println("Image scaling successful");
        return scaledImage;
    }
    */
    
    /**
     * this is super important. ALL graphics must be added to the overridden 
     * paintComponent otherwise they will not be include in java's redraw loop.
     * Meaning otherwise they will show up for one frame only (disappear instantly)
     * 
     * @param g 
     */
    @Override // in order to draw anything you need to override the paint component?
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D graphic2d = (Graphics2D) g;
        
        //paintTest( g);
        paintBG( g );
    }

    
    /**
     * hope fully this works. 
     * Gotten from 
     * http://java.sun.com/products/jfc/tsc/articles/swing2d/index.html.
     * ---
     * note: the component has to be visible on screen before a graphics device can be
     * associated with it
     * ---
     * this need to be further fleshed out to take arbitrary dimensions or images
     *  regular image should go.
     * @param g 
     */
    private void paintBG(Graphics g){//what does the graphics parameter refer to?
        System.out.println("paintBG called");
         // Tile the image to fill our area.
        for (int x = 0; x < columns; x++) {
            for (int y = 0; y < rows; y++) {
                g.drawImage(scaledBGimage, x*pixelsPerSquare, y*pixelsPerSquare, this);
            }
        }
    }
    
    /*no longer needed, maybe keep in painting class later
    public void paintTest(Graphics g){//what does the graphics parameter refer to?
        System.out.println(g);
        Graphics2D g2d = (Graphics2D) g;// cast g to Graphics2D  
        g2d.drawString("test", 20, 20);
        g2d.drawImage(scaledBGimage, 20, 20, this);
        g2d.drawImage(originalBGimage, 40, 20, this);
        //g.drawImage(scaledBGimage, 20, 20, null);
        System.out.println("paint test finnished");
    }
    */
}